# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
import json
import time
from time import sleep
import redis
import requests
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from libs.config import homeInfoUrl as HIU, appConfigUrl as ACU, innerAppApiurl as IAU, customerUrl as CU, awType, userType, contactType, downloadPath, logoFile, redirectDomainIP, wt0, wt1, wt2, itemTitle, itemText, postUrl, redisConf, e0, e1, s1, s2
from Logs.log import log1


url = "https://work.weixin.qq.com/wework_admin/loginpage_wx?from=myhome"


def requestUrl():
    try:
        chromeOptions = webdriver.ChromeOptions()
        prefs = {"download.default_directory": downloadPath}
        chromeOptions.add_experimental_option("prefs", prefs)
        chromeOptions.add_argument('--no-sandbox')
        chromeOptions.set_headless()
        chromeOptions.add_argument('--disable-gpu')
        chromeOptions.add_argument("--window-size=1920,1080")
        chromeOptions.add_argument("--start-maximized")
        dr = webdriver.Chrome(chrome_options=chromeOptions)
        dr.set_page_load_timeout(wt0)
        dr.get(url)
        windows = dr.window_handles
    except Exception as e:
        log1.error("请求失败:{}".format(e))
        return "",  ""
    return dr, windows


def login(dr, windows, redisKey, r):
    try:
        for i in range(5):
            # 提取二维码
            ifr = WebDriverWait(dr, wt0).until(
                lambda driver: dr.find_element_by_xpath("//div[@class='login_wechat_qrcode ww_wechatQrCode_cnt']/iframe"))
            dr.switch_to.frame(ifr)
            qrCodeUrl = WebDriverWait(dr, wt0).until(
                lambda driver: dr.find_element_by_xpath("//img[@class='qrcode_login_img js_qrcode_img']")).get_attribute("src")
            # 保存登录二维码url
            value = {"qrCodeUrl": qrCodeUrl, "status": e0}
            r.hmset(redisKey, value)
            r.expire(redisKey, 300)
            qrCodeUrl = r.hget(redisKey, "qrCodeUrl")
            log1.info("二维码login_url:{}".format(qrCodeUrl))
            # 判断是否扫了二维码
            dr.switch_to.window(windows[0])
            for ii in range(18):
                try:
                    WebDriverWait(dr, 20).until(
                        lambda driver: dr.find_element_by_xpath("//main[@class='frame_cnt frame_cnt_SuperAdmin ']"))
                    # 修改redis状态
                    r.hset(redisKey, "status", s2)
                    return
                except:
                    if i == 4:
                        log1.info("未扫码登录")
                        return True
            dr.refresh()
    except Exception as e:
        log1.info("登录请求失败:{}".format(e))
        return True


def postAWApi(dataDict, envData):
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36",
        "content-type": "application/json;charset=UTF-8"
    }
    log1.info(dataDict["agentId"])
    data = {
        "awName": dataDict["awName"],
        "corpId": dataDict["corpId"],
        "corpList": [
            {
                "callbackUrl": dataDict["appConfigUrl"],
                "aesKey": dataDict["aesKey"],
                "agentId": dataDict["agentId"],
                "corpId": dataDict["corpId"],
                "secret": dataDict["appSecret"],
                "token": dataDict["token"],
                "type": awType,
                "uuid": dataDict["uuid"]
            },
            {
                "callbackUrl": dataDict["innerAppApiurl"],
                "aesKey": dataDict["aesKey"],
                "agentId": dataDict["agentId"],
                "corpId": dataDict["corpId"],
                "secret": dataDict["innerAppSecret"],
                "token": dataDict["token"],
                "type": userType,
                "uuid": dataDict["uuid"]
            },
            {
                "callbackUrl": dataDict["customerUrl"],
                "aesKey": dataDict["aesKey"],
                "agentId": dataDict["agentId"],
                "corpId": dataDict["corpId"],
                "secret": dataDict["customerSecret"],
                "token": dataDict["token"],
                "type": contactType,
                "uuid": dataDict["uuid"]
            }
        ],
        "logo": dataDict["logoUrl"],
        "qrcodeUrl": dataDict["qrcodeUrl"],
        "uuid": dataDict["uuid"]
    }
    resp = requests.post(postUrl.format(envData), headers=headers, json=data)
    resp_dict = json.loads(resp.text)
    if resp_dict.get("returnCode") == 10000:
        log1.info("新增企业号授权管理成功")
    else:
        log1.info("新增企业号授权管理失败")
        return True


def inputUrlTokenAESKey(dr, dataDict, envData=None):
    if dataDict["type"] == 0:
        inputUrl = dataDict["appConfigUrl"]
    elif dataDict["type"] == 1:
        inputUrl = dataDict["innerAppApiurl"]
    else:
        inputUrl = dataDict["customerUrl"]
    UrlInput = WebDriverWait(dr, wt0).until(
        lambda driver: dr.find_element_by_xpath("//input[@name='callback_url']"))
    UrlInput.clear()
    UrlInput.send_keys(inputUrl)
    if dataDict["type"] == 0:
        # 点击生成Token, Aeskey
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='qui_btn ww_btn ww_btn_Big js_resetUrlToken']"))).click()
        sleep(1)
        dataDict["token"] = dr.find_element_by_xpath("//input[@id='inner_app_token']").get_attribute("value")
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='qui_btn ww_btn ww_btn_Big js_resetAESKey']"))).click()
        sleep(1)
        dataDict["aesKey"] = dr.find_element_by_xpath("//input[@id='inner_app_AES']").get_attribute("value")
        sleep(wt1)
        # 请求AW后台接口
        if postAWApi(dataDict, envData):
            return True
    else:
        TokenInput = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//input[@name='url_token']"))
        TokenInput.clear()
        TokenInput.send_keys(dataDict["token"])
        AeskeyInput = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//input[@name='callback_aeskey']"))
        AeskeyInput.clear()
        AeskeyInput.send_keys(dataDict["aesKey"])
    WebDriverWait(dr, wt0).until(
        EC.element_to_be_clickable((By.XPATH, "//*[@class='qui_btn ww_btn ww_btn_Blue js_save_callback']"))).click()
    try:
        WebDriverWait(dr, wt1).until(
            lambda driver: dr.find_element_by_xpath("//*[text()='保存成功']"))
        # 回调成功
        log1.info("{}回调成功".format(dataDict["type"]))
    except:
        # 回调失败
        log1.info("{}回调失败".format(dataDict["type"]))
        return True


def jstreeCheck(dr, num):
    try:
        WebDriverWait(dr, wt1).until(
            lambda driver: dr.find_element_by_xpath("//li[@class='jstree-node  jstree-last jstree-open']/a")).click()
    except:
        pass
    WebDriverWait(dr, wt0).until(
        EC.element_to_be_clickable((By.XPATH, "//div[@style='position: absolute; z-index: 12{}; top: 0px; left: 0px;']//a[@class='qui_btn ww_btn ww_btn_Blue js_submit']".format(num)))).click()
    sleep(wt2)


def menuProfile(dr, dataDict):
    try:
        # 进入我的企业
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@id='menu_profile']"))).click()
        # 点击企业信息
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[text()='企业信息']"))).click()
        # 企业简称,ID
        shareName = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//span[@class='profile_enterprise_item_shareName']")).text.strip()
        shareID = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//div[text()='企业ID']/..//div[@class='profile_enterprise_item_main']")).text.strip()
        # 外部沟通管理修改成员使用权限
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[text()='外部沟通管理']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='js_show_white_mod']"))).click()
        jstreeCheck(dr, 0)
        # 进入微信插件
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[text()='微信插件']"))).click()
        logoUrl = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//img[@class='wxplugin_setting_panel_logo']")).get_attribute("src")
        qrcodeUrl = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//img[@class='wxplugin_setting_panel_qrcode']")).get_attribute("src")
        dataDict["awName"] = shareName
        dataDict["corpId"] = shareID
        dataDict["logoUrl"] = logoUrl
        dataDict["qrcodeUrl"] = qrcodeUrl
    except Exception as e:
        log1.error("我的企业配置失败:{}".format(e))
        return True


def menuApps(dr, dataDict, envData):
    try:
        # 获取innerAppSecret,customerSecret
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@id='menu_manageTools']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='manageTools_cnt_itemLink js_show_contactsHelpers']"))).click()
        sleep(wt2)
        # 开启API接口同步
        try:
            WebDriverWait(dr, wt1).until(
                EC.element_to_be_clickable((By.XPATH, "//a[text()='开启API接口同步']"))).click()
            sleep(wt2)
        except:
            pass
        innerAppSecret = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//span[@id='inner_app_secret']")).text
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@id='menu_customer']"))).click()
        sleep(wt2)
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@data-name='analysis']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//span[@class='ww_icon js_wxContacts_api_folder_button util_ml_smaller ww_icon_AttendanceApiOff']"))).click()
        sleep(wt2)
        customerSecret = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//span[@class='js_wxContacts_api_secret']")).text
        # 进入应用管理
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@id='menu_apps']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//div[@class='app_index_section_cnt js_openapi_block']//a[@class='app_index_item_title js_add_app']"))).click()
        # 上传logo
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='ww_fileInputWrap']"))).click()
        upload = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//div[@class='cropper_topContainer ']//input[@class='ww_fileInput js_file']"))
        # 选择本地文件
        upload.clear()
        upload.send_keys(logoFile)
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='qui_btn ww_btn ww_btn_Blue js_save']"))).click()
        sleep(wt2)
        # 输入名称与介绍
        nameInput = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//input[@name='name']"))
        nameInput.clear()
        nameInput.send_keys(itemTitle)
        textArea = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//textarea[@name='description']"))
        textArea.clear()
        textArea.send_keys(itemText)
        # 选择部门/成员
        try:
            WebDriverWait(dr, wt1).until(
                EC.element_to_be_clickable((By.XPATH, "//a[@class='apiApp_create_scopeItem_btn js_show_visible_add']"))).click()
        except:
            WebDriverWait(dr, wt0).until(
                EC.element_to_be_clickable(
                    (By.XPATH, "//a[@class='ww_groupSelBtn_add js_show_visible_mod']"))).click()
        jstreeCheck(dr, 2)
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='qui_btn ww_btn ww_btn_Blue ww_btn_Large apiApp_create_submitBtn js_create_app']"))).click()
        sleep(wt1)
        agentId = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//div[@class='app_stage_section_cnt app_stage_section_cnt_Done']//div[@class='apiApp_mod_rowItem']/div[@class='apiApp_mod_rowItem_cnt']")).text
        appSecret = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//div[@class='app_stage_section_cnt app_stage_section_cnt_Done']//div[@class='apiApp_mod_rowItem apiApp_mod_basicInfoSection_secretItem']/div[@class='apiApp_mod_rowItem_cnt']")).text
        # 设置应用主页
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//div[@class='app_cardInner']//a[@class='js_edit_home_url']"))).click()
        homeInfoUrl = HIU.format(envData, dataDict["corpId"])
        homeInfoUrlInput = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//input[@class='qui_inputText ww_inputText']"))
        homeInfoUrlInput.clear()
        homeInfoUrlInput.send_keys(homeInfoUrl)
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='qui_btn ww_btn ww_btn_Blue']"))).click()
        sleep(wt2)
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//input[@class='js_home_info_url_checkbox ww_checkbox']"))).click()
        # 设置可信域名
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='js_edit_redirect_domain']"))).click()
        redirectDomainIPInput = WebDriverWait(dr, wt0).until(
            lambda driver: dr.find_element_by_xpath("//input[@name='redirect_domain_noIP']"))
        redirectDomainIPInput.clear()
        redirectDomainIPInput.send_keys(redirectDomainIP.format(envData))
        # 申请校验域名
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='js_own_domain_apply']"))).click()
        # 下载文件
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[text()='下载文件']"))).click()
        sleep(wt1)
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//input[@class='ww_checkbox js_own_domain_confirm']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='qui_btn ww_btn ww_btn_Blue']"))).click()
        sleep(wt2)
        # 设置接收消息
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='js_show_edit_callback']"))).click()
        appConfigUrl = ACU.format(envData, dataDict["corpId"])
        innerAppApiurl = IAU.format(envData, dataDict["corpId"])
        customerUrl = CU.format(envData, dataDict["corpId"])
        dataDict["agentId"] = agentId
        dataDict["appConfigUrl"] = appConfigUrl
        dataDict["innerAppApiurl"] = innerAppApiurl
        dataDict["customerUrl"] = customerUrl
        dataDict["appSecret"] = appSecret
        dataDict["innerAppSecret"] = innerAppSecret
        dataDict["customerSecret"] = customerSecret
        dataDict["itemTitle"] = itemTitle
        dataDict["type"] = awType
        if inputUrlTokenAESKey(dr, dataDict, envData):
            return True
    except Exception as e:
        log1.error("应用管理配置失败:{}".format(e))
        return True


def menuManageTools(dr, dataDict):
    try:
        # 进入管理工具
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@id='menu_manageTools']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='manageTools_cnt_itemLink js_show_contactsHelpers']"))).click()
        sleep(wt2)
        # 开启API接口同步
        try:
            WebDriverWait(dr, wt1).until(
                EC.element_to_be_clickable((By.XPATH, "//a[text()='开启API接口同步']"))).click()
            sleep(wt2)
        except:
            pass
        # 权限编辑(读写)
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='contactsSync_infoItem_content_link js_enter_editing']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//input[@value='1']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='qui_btn ww_btn ww_btn_Blue js_save_editing']"))).click()
        sleep(wt2)
        # 设置接收事件服务器
        try:
            WebDriverWait(dr, wt1).until(
                EC.element_to_be_clickable((By.XPATH, "//a[@class='contactsSync_infoItem_title_link js_show_edit_callback']"))).click()
        except:
            WebDriverWait(dr, wt0).until(
                EC.element_to_be_clickable((By.XPATH, "//a[@class='contactsSync_infoItem_content_link js_show_edit_callback']"))).click()
        dataDict["type"] = userType
        if inputUrlTokenAESKey(dr, dataDict):
            return True
    except Exception as e:
        log1.error("管理工具配置失败:{}".format(e))
        return True


def menuCustomer(dr, dataDict):
    try:
        # 进入客户联系
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@id='menu_customer']"))).click()
        dr.refresh()
        sleep(wt2)
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@data-name='analysis']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//span[@class='ww_icon js_wxContacts_api_folder_button util_ml_smaller ww_icon_AttendanceApiOff']"))).click()
        sleep(wt2)
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='js_show_app_list']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//span[text()='{}']/../span[@class='profile_role_dialog_checkboxWrap']//input".format(dataDict["itemTitle"])))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='qui_btn ww_btn ww_btn_Blue']"))).click()
        sleep(wt2)
        # 接收事件服务器设置
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@class='js_show_edit_callback']"))).click()
        dataDict["type"] = contactType
        edit_result = inputUrlTokenAESKey(dr, dataDict)
        try:
            WebDriverWait(dr, wt1).until(
                EC.element_to_be_clickable((By.XPATH, "//a[@class='qui_btn ww_btn ww_btn_Back js_back_btn']"))).click()
            sleep(wt2)
        except:
            pass
        # 配置
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@data-name='config']"))).click()
        WebDriverWait(dr, wt0).until(
            EC.element_to_be_clickable((By.XPATH, "//a[@href='#customer/group']"))).click()
        try:
            # 添加 客户联系和客户群使用范围
            WebDriverWait(dr, wt1).until(
                EC.element_to_be_clickable((By.XPATH, "//a[@on-click='onEditFollowers']"))).click()
            jstreeCheck(dr, 4)
            WebDriverWait(dr, wt1).until(
                EC.element_to_be_clickable((By.XPATH, "//a[@on-click='onEditFollowersSave']"))).click()
        except:
            pass
        try:
            # 添加 客户朋友圈使用范围
            WebDriverWait(dr, wt1).until(
                EC.element_to_be_clickable((By.XPATH, "//a[@on-click='onEditMomentsFollowers']"))).click()
            jstreeCheck(dr, 6)
            WebDriverWait(dr, wt1).until(
                EC.element_to_be_clickable((By.XPATH, "//a[@on-click='onEditMomentsFollowersSave']"))).click()
        except:
            pass
        if edit_result:
            return True
    except Exception as e:
        log1.error("客户联系配置失败:{}".format(e))
        return True


def run(dataList):
    uuid = dataList[1].strip()
    envType = dataList[2].strip().lower()
    redisKey = "AUTODATA:{}".format(uuid)
    result = {}
    dataDict = {}
    dataDict["uuid"] = uuid
    if envType not in ["sit", "uat", "helper"]:
        log1.info("环境变量参数不匹配")
        result["error"] = "环境变量参数只支持sit, uat, helper其中一个"
        return result
    try:
        # redis连接
        redisHost, redisPort, redisPwd, redisDb = redisConf(envType)
        pool = redis.ConnectionPool(host=redisHost, port=redisPort, password=redisPwd, db=redisDb, decode_responses=True)
        r = redis.Redis(connection_pool=pool)
    except Exception as e:
        log1.info("redis连接失败:{}".format(e))
        result["error"] = "redis连接失败"
        return result
    dr, windows = requestUrl()
    if not (dr or windows):
        result["error"] = "网络异常请求企业微信后台失败!请重试"
        r.hset(redisKey, "status", e1)
        r.hset(redisKey, "result", result["error"])
        return result
    if login(dr, windows, redisKey, r):
        result["error"] = "未扫码登录或登录异常!请重试"
        r.hset(redisKey, "status", e1)
        r.hset(redisKey, "result", result["error"])
        return result
    if menuProfile(dr, dataDict):  # 我的应用
        result["error"] = "网络异常,我的应用配置失败!请重试"
        r.hset(redisKey, "status", e1)
        r.hset(redisKey, "result", result["error"])
        return result
    if menuApps(dr, dataDict, envType):  # 应用管理
        result["error"] = "网络异常,应用管理配置失败!请重试"
        r.hset(redisKey, "status", e1)
        r.hset(redisKey, "result", result["error"])
        return result
    if menuManageTools(dr, dataDict):  # 管理工具
        result["error"] = "网络异常,管理工具配置失败!请重试"
        r.hset(redisKey, "status", e1)
        r.hset(redisKey, "result", result["error"])
        return result
    if menuCustomer(dr, dataDict):  # 客户联系
        result["error"] = "网络异常,客户联系配置失败!请重试"
        r.hset(redisKey, "status", e1)
        r.hset(redisKey, "result", result["error"])
        return result
    # 配置成功
    result["success"] = "配置成功!"
    log1.info("配置成功")
    r.hset(redisKey, "status", s1)
    r.hset(redisKey, "result", result["success"])
    dr.close()
    return result


if __name__ == '__main__':
    import sys
    start = time.time()
    result = run(sys.argv)
    end = time.time()
    log1.info("程序完毕,共耗时:{}S".format(end-start))
